/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.drawee.drawable;

import com.oszc.bbhmlibrary.utils.LogUtil;
import ohos.agp.components.Component;
import ohos.agp.components.element.Element;
import ohos.agp.render.Canvas;
import ohos.agp.render.ColorFilter;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.agp.utils.RectFloat;

/**
 * Drawable that displays a progress bar based on the level.
 */
public class ProgressBarDrawable extends RootShapeElement implements CloneableDrawable {

    private final String TAG = ProgressBarDrawable.class.getSimpleName();
    private final Paint mPaint = new Paint();
    private final Path mPath = new Path();
    private final RectFloat mRect = new RectFloat();
    private int mBackgroundColor = 0x80000000;
    private int mColor = 0x800080FF;
    private int mPadding = 2;
    private int mBarWidth = 20;
    private int mLevel = 0;
    private int mRadius = 0;
    private boolean mHideWhenZero = false;
    private boolean mIsVertical = false;

    public Component mComponent;

    /**
     * Sets the progress bar color.
     */
    public void setColor(int color) {
        if (mColor != color) {
            mColor = color;
            invalidateSelf();
        }
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }

    /**
     * Gets the progress bar color.
     */
    public int getColor() {
        return mColor;
    }

    /**
     * Sets the progress bar background color.
     */
    public void setBackgroundColor(int backgroundColor) {
        if (mBackgroundColor != backgroundColor) {
            mBackgroundColor = backgroundColor;
            invalidateSelf();
        }
    }

    /**
     * Gets the progress bar background color.
     */
    public int getBackgroundColor() {
        return mBackgroundColor;
    }

    /**
     * Sets the progress bar padding.
     */
    public void setPadding(int padding) {
        if (mPadding != padding) {
            mPadding = padding;
            invalidateSelf();
        }
    }

    /**
     * Gets the progress bar padding.
     */
    public boolean getPadding(Rect padding) {
        padding.set(mPadding, mPadding, mPadding, mPadding);
        return mPadding != 0;
    }

    /**
     * Sets the progress bar width.
     */
    public void setBarWidth(int barWidth) {
        if (mBarWidth != barWidth) {
            mBarWidth = barWidth;
            invalidateSelf();
        }
    }

    /**
     * Gets the progress bar width.
     */
    public int getBarWidth() {
        return mBarWidth;
    }

    /**
     * Sets whether the progress bar should be hidden when the progress is 0.
     */
    public void setHideWhenZero(boolean hideWhenZero) {
        mHideWhenZero = hideWhenZero;
    }

    /**
     * Gets whether the progress bar should be hidden when the progress is 0.
     */
    public boolean getHideWhenZero() {
        return mHideWhenZero;
    }

    /**
     * The progress bar will be displayed as a rounded corner rectangle, sets the radius here.
     */
    public void setRadius(int radius) {
        if (mRadius != radius) {
            mRadius = radius;
            invalidateSelf();
        }
    }

    /**
     * Gets the radius of the progress bar.
     */
    public int getRadius() {
        return mRadius;
    }

    /**
     * Sets if the progress bar should be vertical.
     */
    public void setIsVertical(boolean isVertical) {
        if (mIsVertical != isVertical) {
            mIsVertical = isVertical;
            invalidateSelf();
        }
    }

    /**
     * Gets if the progress bar is vertical.
     */
    public boolean getIsVertical() {
        return mIsVertical;
    }

    @Override
    public boolean onLevelChange(int level) {
        LogUtil.error(TAG, "onLevelChange:" + level);
        mLevel = level;
        invalidateSelf();
        return true;
    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
    }

//  @Override
//  public void setColorFilter(ColorFilter cf) {
//    mPaint.setColorFilter(cf);
//  }
//
//  @Override
//  public int getOpacity() {
//    return DrawableUtils.getOpacityFromColor(mPaint.getColor());
//  }

    @Override
    public void drawToCanvas(Canvas canvas) {
        LogUtil.error(TAG, "drawToCanvas:" + mLevel);
        if (mHideWhenZero && mLevel == 0) {
            return;
        }
        if (mIsVertical) {
            drawVerticalBar(canvas, 10000, mBackgroundColor);
            drawVerticalBar(canvas, mLevel, mColor);
        } else {
            drawHorizontalBar(canvas, 10000, mBackgroundColor);
            drawHorizontalBar(canvas, mLevel, mColor);
        }
    }


    public void setComponent(Component component) {
        mComponent = component;
    }

    public void invalidateSelf() {
       // LogUtil.error(TAG,"invalidateSelf A" );
        /*
        if (mComponent != null) {
        //    LogUtil.error(TAG,"invalidateSelf B");
            mComponent.addDrawTask((component, canvas) -> drawToCanvas(canvas));
        }
         */
        if(getCallback()!=null){
            getCallback().onChange(this);
        }
    }

    @Override
    public Element cloneDrawable() {
        final ProgressBarDrawable copy = new ProgressBarDrawable();
        copy.mBackgroundColor = mBackgroundColor;
        copy.mColor = mColor;
        copy.mPadding = mPadding;
        copy.mBarWidth = mBarWidth;
        copy.mLevel = mLevel;
        copy.mRadius = mRadius;
        copy.mHideWhenZero = mHideWhenZero;
        copy.mIsVertical = mIsVertical;
        return copy;
    }


    private void drawHorizontalBar(Canvas canvas, int level, int color) {
        Rect bounds = getBounds();
        int length = (bounds.getWidth() - 2 * mPadding) * level / 10000;
  //      LogUtil.error(TAG,"drawHorizontalBar: bounds:" + bounds + "length: "+length);
        int xpos = bounds.left + mPadding;
        int ypos = bounds.bottom - mPadding - mBarWidth;
//    mRect.set(xpos, ypos, xpos + length, ypos + mBarWidth);
        mRect.left = xpos;
        mRect.top = ypos;
        mRect.right = xpos + length;
        mRect.bottom = ypos + mBarWidth;
        drawBar(canvas, color);
    }

    private void drawVerticalBar(Canvas canvas, int level, int color) {
        Rect bounds = getBounds();
        int length = (bounds.getWidth() - 2 * mPadding) * level / 10000;
        int xpos = bounds.left + mPadding;
        int ypos = bounds.top + mPadding;
//    mRect.set(xpos, ypos, xpos + mBarWidth, ypos + length);
        mRect.left = xpos;
        mRect.top = ypos;
        mRect.right = xpos + mBarWidth;
        mRect.bottom = ypos + length;
        drawBar(canvas, color);
    }

    private void drawBar(Canvas canvas, int color) {
        mPaint.setAntiAlias(true);
        mPaint.setColor(new Color(color));
        mPaint.setStyle(Paint.Style.FILLANDSTROKE_STYLE);
        mPath.reset();
        mPath.setFillType(Path.FillType.EVEN_ODD);
        mPath.addRoundRect(
                mRect,
                Math.min(mRadius, mBarWidth / 2),
                Math.min(mRadius, mBarWidth / 2),
                Path.Direction.CLOCK_WISE);
        LogUtil.error(TAG,"drawBar: mRect:"+mRect);
        canvas.drawPath(mPath, mPaint);
    }
}
